/******************************************************************************
 * * alarm_ui.c - UI display of alarm module
 *
 * *(C) Copyright 2019 Asr International Ltd.
 * * All Rights Reserved
 * ******************************************************************************/

#include "alarm_global.h"

/**
 * common create function
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Create_Common(VOID *pDesc)
{
    g_Alarm_Mng.CurrDesc = pDesc;
}

/**
 * common destroy function
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Destroy_Common(VOID *pDesc)
{
    Hal_Mem_Free(pDesc);
    g_Alarm_Mng.CurrDesc = NULL;
}

/**
 * common function for destroy list only
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Destroy_ListOnly(VOID *pDesc)
{
    UI_Normal_List_Only_Desc_t *Desc = pDesc;

    Hal_Mem_Free(Desc->List.ButtonList);

    Alarm_Destroy_Common(pDesc);
}

/**
 * common function for destroy container list
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Destroy_ContList(VOID *pDesc)
{
    UI_Normal_Container_List_Desc_t *Desc = pDesc;

    Hal_Mem_Free(Desc->ContList.ContainerList);

    Alarm_Destroy_Common(pDesc);
}

/**
 * create function of Alarm
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Create(VOID *pDesc)
{
    UI_Normal_Container_List_Desc_t *pContListDesc = NULL;

    pContListDesc = (UI_Normal_Container_List_Desc_t *)pDesc;

    lv_label_set_text(pContListDesc->ContList.ContainerList[0].u.Label2.Label, "");
    if (0 != g_Alarm_Mng.Alarm.ToneIndex)
    {
        lv_label_set_text(pContListDesc->ContList.ContainerList[1].u.Label2.Label, g_Alarm_Ringing_Tone[g_Alarm_Mng.Alarm.ToneIndex]);
    }

    Alarm_Create_Common(pDesc);
}

/**
 * create function of Alarm Set
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Set_Create(VOID *pDesc)
{
    UI_Normal_Container_List_Desc_t *pContListDesc = NULL;
    INT8                            LabelTxt[6];
    UINT8                           i;

    pContListDesc = (UI_Normal_Container_List_Desc_t *)pDesc;

    for (i = 0; i < NV_ALARM_MAX_ALARM_NUM; i++)
    {
        if (TRUE == g_Alarm_Mng.Alarm.AlarmInfo[i].OnOff)
        {
            sprintf(LabelTxt, "%02d:%02d", g_Alarm_Mng.Alarm.AlarmInfo[i].Hour, g_Alarm_Mng.Alarm.AlarmInfo[i].Min);
            lv_label_set_text(pContListDesc->ContList.ContainerList[i].u.Label2.Label, LabelTxt);
        }
    }

    Alarm_Create_Common(pDesc);
}

/**
 *
 * Create function of Alarm_Set_Time
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Set_Time_Create(VOID *pDesc)
{
    Alarm_Create_Common(pDesc);
}

/**
 *
 * Save function of Alarm_Set_Time
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Set_Time_Save(VOID *pDesc)
{
    UI_Normal_Time_Desc_t *pNormalTimeDesc = NULL;

    pNormalTimeDesc = (UI_Normal_Time_Desc_t *)pDesc;

    INT8 Buf[3] = {0};
    lv_roller_get_selected_str(pNormalTimeDesc->ContTime.Roller1.Roller, Buf, 0);
    pNormalTimeDesc->ContTime.Roller1.MidValue = atoi(Buf);
    lv_roller_get_selected_str(pNormalTimeDesc->ContTime.Roller2.Roller, Buf, 0);
    pNormalTimeDesc->ContTime.Roller2.MidValue = atoi(Buf);
}

/**
 *
 * Destroy function of Alarm_Set_Time
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Set_Time_Destroy(VOID *pDesc)
{
    Alarm_Destroy_Common(pDesc);
}

/**
 * display Alarm
 */
VOID Display_Alarm(VOID)
{
    Nav_Func_List_t                 FuncList;
    UI_Normal_Container_List_Desc_t *pDesc = NULL;
    UINT8                           i      = 0;

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_Container_List_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create;
    FuncList.OnDestroy      = Alarm_Destroy_ContList;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Create;

    pDesc = (UI_Normal_Container_List_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_Container_List_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_Container_List_Desc_t));

    pDesc->TitleBar.TxtId            = PHONE_TEXT_ID_ALARM;
    pDesc->TitleBar.TxtAlign         = LV_LABEL_ALIGN_CENTER;
    pDesc->ContList.Index            = 0;
    pDesc->ContList.ListContainerCnt = 2;
    pDesc->ContList.ContainerList    = (UI_Container_Base_Desc_t *)Hal_Mem_Alloc(
        sizeof(UI_Container_Base_Desc_t) * pDesc->ContList.ListContainerCnt);
    Hal_Mem_Set(pDesc->ContList.ContainerList, 0,
                sizeof(UI_Container_Base_Desc_t) * pDesc->ContList.ListContainerCnt);

    pDesc->ContList.ContainerList[i].Valid             = TRUE;
    pDesc->ContList.ContainerList[i].Label.TxtId       = PHONE_TEXT_ID_SET_ALARM; // Set Alarm
    pDesc->ContList.ContainerList[i].Label.TxtAlign    = LV_LABEL_ALIGN_LEFT;
    pDesc->ContList.ContainerList[i].Label.SymbolId    = SYMBOL_ALARM;
    pDesc->ContList.ContainerList[i].Choise            = UI_BASE_OBJ_LABEL;
    pDesc->ContList.ContainerList[i].u.Label2.TxtId    = LV_LANG_TXT_ID_NONE;
    pDesc->ContList.ContainerList[i].u.Label2.TxtAlign = LV_LABEL_ALIGN_RIGHT;
    pDesc->ContList.ContainerList[i++].ReleaseFunc     = Alarm_Proc_Btn_Set_Alarm;

    pDesc->ContList.ContainerList[i].Valid             = TRUE;
    pDesc->ContList.ContainerList[i].Label.TxtId       = PHONE_TEXT_ID_ALARM_TONE; // Alarm Tone
    pDesc->ContList.ContainerList[i].Label.TxtAlign    = LV_LABEL_ALIGN_LEFT;
    pDesc->ContList.ContainerList[i].Label.SymbolId    = LV_SYMBOL_AUDIO;
    pDesc->ContList.ContainerList[i].Choise            = UI_BASE_OBJ_LABEL;
    pDesc->ContList.ContainerList[i].u.Label2.TxtId    = PHONE_TEXT_ID_STANDARD;
    pDesc->ContList.ContainerList[i].u.Label2.TxtAlign = LV_LABEL_ALIGN_RIGHT;
    pDesc->ContList.ContainerList[i++].ReleaseFunc     = Alarm_Proc_Btn_Alarm_Tone;

    pDesc->ButtonBar.ButtonM.Valid = TRUE;
    pDesc->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;
    pDesc->ButtonBar.ButtonR.Valid = TRUE;
    pDesc->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pDesc->KeyFunc                 = Alarm_Proc_Key_Alarm;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM, &FuncList, pDesc);
} /* Display_Alarm */

/**
 * Get text id from alarm id
 */
UI_PHONE_TEXT_ID Alarm_Get_Alarm_Text_Id(UINT8 AlarmId)
{
    UI_PHONE_TEXT_ID TxtId = PHONE_TEXT_ID_ALARM1;

    switch (AlarmId)
    {
    case 0:
        TxtId = PHONE_TEXT_ID_ALARM1;
        break;

    case 1:
        TxtId = PHONE_TEXT_ID_ALARM2;
        break;

    case 2:
        TxtId = PHONE_TEXT_ID_ALARM3;
        break;

    case 3:
        TxtId = PHONE_TEXT_ID_ALARM4;
        break;

    case 4:
        TxtId = PHONE_TEXT_ID_ALARM5;
        break;

    default:
        break;
    }

    return(TxtId);
}

/**
 * display Alarm Set
 */
VOID Display_Alarm_Set(VOID)
{
    Nav_Func_List_t                 FuncList;
    UI_Normal_Container_List_Desc_t *pDesc = NULL;
    UINT8                           i      = 0;

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_Container_List_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Set_Create;
    FuncList.OnDestroy      = Alarm_Destroy_ContList;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Set_Create;

    pDesc = (UI_Normal_Container_List_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_Container_List_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_Container_List_Desc_t));

    pDesc->TitleBar.TxtId            = PHONE_TEXT_ID_ALARM;
    pDesc->TitleBar.TxtAlign         = LV_LABEL_ALIGN_CENTER;
    pDesc->ContList.Index            = 0;
    pDesc->ContList.ListContainerCnt = NV_ALARM_MAX_ALARM_NUM;
    pDesc->ContList.ContainerList    = (UI_Container_Base_Desc_t *)Hal_Mem_Alloc(
        sizeof(UI_Container_Base_Desc_t) * pDesc->ContList.ListContainerCnt);
    Hal_Mem_Set(pDesc->ContList.ContainerList, 0,
                sizeof(UI_Container_Base_Desc_t) * pDesc->ContList.ListContainerCnt);

    for (i = 0; i < NV_ALARM_MAX_ALARM_NUM; i++)
    {
        pDesc->ContList.ContainerList[i].Valid             = TRUE;
        pDesc->ContList.ContainerList[i].Label.TxtAlign    = LV_LABEL_ALIGN_LEFT;
        pDesc->ContList.ContainerList[i].Choise            = UI_BASE_OBJ_LABEL;
        pDesc->ContList.ContainerList[i].u.Label2.TxtId    = PHONE_TEXT_ID_OFF;
        pDesc->ContList.ContainerList[i].u.Label2.TxtAlign = LV_LABEL_ALIGN_RIGHT;
        pDesc->ContList.ContainerList[i].Label.TxtId       = Alarm_Get_Alarm_Text_Id(i);
        if (0 == i)
        {
            pDesc->ContList.ContainerList[i].ReleaseFunc = Alarm_Proc_Btn_Alarm1;
        }
        else if (1 == i)
        {
            pDesc->ContList.ContainerList[i].ReleaseFunc = Alarm_Proc_Btn_Alarm2;
        }
    }

    pDesc->ButtonBar.ButtonM.Valid = TRUE;
    pDesc->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;
    pDesc->ButtonBar.ButtonR.Valid = TRUE;
    pDesc->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pDesc->KeyFunc                 = Alarm_Proc_Key_Alarm_Set;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_SET, &FuncList, pDesc);
} /* Display_Alarm_Set */

/**
 * display Alarm Set Time
 */
VOID Display_Alarm_Set_Time(BOOL New)
{
    Nav_Func_List_t       FuncList;
    UI_Normal_Time_Desc_t *pNormalTimeDesc;
    hal_rtc_t             Time;

    FuncList.OnShow         = UI_Normal_Time_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Set_Time_Create;
    FuncList.OnDestroy      = Alarm_Set_Time_Destroy;
    FuncList.OnSaveState    = Alarm_Set_Time_Save;
    FuncList.OnRestoreState = Alarm_Set_Time_Create;

    pNormalTimeDesc = Hal_Mem_Alloc(sizeof(UI_Normal_Time_Desc_t));
    Hal_Mem_Set(pNormalTimeDesc, 0, sizeof(UI_Normal_Time_Desc_t));

    // Hours
    pNormalTimeDesc->TitleBar.TxtId      = PHONE_TEXT_ID_SET_ALARM_TIME;
    pNormalTimeDesc->TitleBar.TxtAlign   = LV_LABEL_ALIGN_CENTER;
    pNormalTimeDesc->TitleBar.LabelAlign = LV_ALIGN_IN_TOP_LEFT;

    pNormalTimeDesc->ContTime.Roller1.RollerType = UI_ROLLER_TYPE_HOUR;
    pNormalTimeDesc->ContTime.Roller2.RollerType = UI_ROLLER_TYPE_MINUTE;
    if (TRUE == New)
    {
        Hal_Rtc_Gettime(&Time);
        pNormalTimeDesc->ContTime.Roller1.MidValue = Time.tm_hour;
        pNormalTimeDesc->ContTime.Roller2.MidValue = Time.tm_min;
    }
    else
    {
        pNormalTimeDesc->ContTime.Roller1.MidValue
            = g_Alarm_Mng.Alarm.AlarmInfo[g_Alarm_Mng.CurrAlarmId].Hour;
        pNormalTimeDesc->ContTime.Roller2.MidValue
            = g_Alarm_Mng.Alarm.AlarmInfo[g_Alarm_Mng.CurrAlarmId].Min;
    }

    pNormalTimeDesc->ButtonBar.ButtonM.Valid = TRUE;
    pNormalTimeDesc->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_OK;
    pNormalTimeDesc->ButtonBar.ButtonR.Valid = TRUE;
    pNormalTimeDesc->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pNormalTimeDesc->KeyFunc                 = Alarm_Proc_Key_Alarm_Set_Time;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_SET_TIME, &FuncList, pNormalTimeDesc);
} /* Display_Alarm_Set_Time */

/**
 * display Alarm Edit
 */
VOID Display_Alarm_Edit(VOID)
{
    Nav_Func_List_t            FuncList;
    UI_Normal_List_Only_Desc_t *pDesc = NULL;
    UINT32                     Size   = 0;
    UINT8                      i      = 0;

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_List_Only_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create_Common;
    FuncList.OnDestroy      = Alarm_Destroy_ListOnly;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Create_Common;

    pDesc = (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    pDesc->TitleBar.TxtId    = PHONE_TEXT_ID_ALARM;
    pDesc->TitleBar.TxtAlign = LV_LABEL_ALIGN_CENTER;

    pDesc->List.ListButtonCnt = 3;
    Size                      = sizeof(UI_Button_Desc_t) * pDesc->List.ListButtonCnt;
    pDesc->List.ButtonList    = (UI_Button_Desc_t *)Hal_Mem_Alloc(Size);
    Hal_Mem_Set(pDesc->List.ButtonList, 0, Size);

    pDesc->List.ButtonList[i].Valid        = TRUE;
    pDesc->List.ButtonList[i].ButtonIndex  = i;
    pDesc->List.ButtonList[i].TxtId        = PHONE_TEXT_ID_ALARM_ADJUST;    // Adjust
    pDesc->List.ButtonList[i++].ReleaseFun = Alarm_Proc_Btn_Adjust;

    pDesc->List.ButtonList[i].Valid        = TRUE;
    pDesc->List.ButtonList[i].ButtonIndex  = i;
    pDesc->List.ButtonList[i].TxtId        = PHONE_TEXT_ID_OFF; // Off
    pDesc->List.ButtonList[i++].ReleaseFun = Alarm_Proc_Btn_Off;

    pDesc->List.ButtonList[i].Valid        = TRUE;
    pDesc->List.ButtonList[i].ButtonIndex  = i;
    pDesc->List.ButtonList[i].TxtId        = PHONE_TEXT_ID_ALARM_REPEAT; // Repeat alarm
    pDesc->List.ButtonList[i++].ReleaseFun = Alarm_Proc_Btn_Repeat;

    pDesc->BtnBar.ButtonM.Valid = TRUE;
    pDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_OK;
    pDesc->BtnBar.ButtonR.Valid = TRUE;
    pDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pDesc->KeyFunc              = Alarm_Proc_Key_Alarm_Edit;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_EDIT, &FuncList, pDesc);
} /* Display_Alarm_Edit */

/**
 * display Alarm Repeat
 */
VOID Display_Alarm_Repeat(VOID)
{
    Nav_Func_List_t            FuncList;
    UI_Normal_List_Only_Desc_t *pDesc = NULL;
    UINT32                     Size   = 0;
    UINT8                      i      = 0;

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_List_Only_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create_Common;
    FuncList.OnDestroy      = Alarm_Destroy_ListOnly;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Create_Common;

    pDesc = (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    pDesc->TitleBar.TxtId    = PHONE_TEXT_ID_ALARM;
    pDesc->TitleBar.TxtAlign = LV_LABEL_ALIGN_CENTER;

    pDesc->List.ListButtonCnt = 2;
    if (0 == (g_Alarm_Mng.Alarm.AlarmInfo[g_Alarm_Mng.CurrAlarmId].RepeatBitmap & 0x80))
    {
        pDesc->List.Index = 0;  // once
    }
    else
    {
        pDesc->List.Index = 1;  // repeat
    }

    Size                   = sizeof(UI_Button_Desc_t) * pDesc->List.ListButtonCnt;
    pDesc->List.ButtonList = (UI_Button_Desc_t *)Hal_Mem_Alloc(Size);
    Hal_Mem_Set(pDesc->List.ButtonList, 0, Size);

    pDesc->List.ButtonList[i].Valid        = TRUE;
    pDesc->List.ButtonList[i].ButtonIndex  = i;
    pDesc->List.ButtonList[i].TxtId        = PHONE_TEXT_ID_ALARM_MODE_ONCE;    // Alarm once
    pDesc->List.ButtonList[i++].ReleaseFun = Alarm_Proc_Btn_Mode_Once;

    pDesc->List.ButtonList[i].Valid        = TRUE;
    pDesc->List.ButtonList[i].ButtonIndex  = i;
    pDesc->List.ButtonList[i].TxtId        = PHONE_TEXT_ID_ALARM_MODE_REPEAT; // Repeat alarm
    pDesc->List.ButtonList[i++].ReleaseFun = Alarm_Proc_Btn_Mode_Repeat;

    pDesc->BtnBar.ButtonM.Valid = TRUE;
    pDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_OK;
    pDesc->BtnBar.ButtonR.Valid = TRUE;
    pDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pDesc->KeyFunc              = Alarm_Proc_Key_Alarm_Repeat;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_REPEAT, &FuncList, pDesc);
} /* Display_Alarm_Repeat */

/**
 * display Alarm Repeat Select
 */
VOID Display_Alarm_Repeat_Select(VOID)
{
    Nav_Func_List_t            FuncList;
    UI_Normal_List_Only_Desc_t *pDesc       = NULL;
    UINT32                     Size         = 0;
    UINT8                      RepeatBitmap = 0;
    UINT8                      i            = 0;
    UINT16                     TxtId[7]     =
    {
        PHONE_TEXT_ID_WDAY_SUNDAY,
        PHONE_TEXT_ID_WDAY_MONDAY,
        PHONE_TEXT_ID_WDAY_TUESDAY,
        PHONE_TEXT_ID_WDAY_WEDNESDAY,
        PHONE_TEXT_ID_WDAY_THURSDAY,
        PHONE_TEXT_ID_WDAY_FRIDAY,
        PHONE_TEXT_ID_WDAY_SATURDAY
    };

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_List_Only_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create_Common;
    FuncList.OnDestroy      = Alarm_Destroy_ListOnly;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Create_Common;

    pDesc = (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    pDesc->TitleBar.TxtId    = PHONE_TEXT_ID_ALARM_MODE_REPEAT;
    pDesc->TitleBar.TxtAlign = LV_LABEL_ALIGN_CENTER;

    pDesc->List.ListButtonCnt = 7;
    Size                      = sizeof(UI_Button_Desc_t) * pDesc->List.ListButtonCnt;
    pDesc->List.ButtonList    = (UI_Button_Desc_t *)Hal_Mem_Alloc(Size);
    Hal_Mem_Set(pDesc->List.ButtonList, 0, Size);

    RepeatBitmap                 = g_Alarm_Mng.Alarm.AlarmInfo[g_Alarm_Mng.CurrAlarmId].RepeatBitmap;
    g_Alarm_Mng.RepeatBitmapTemp = RepeatBitmap;

    for (i = 0; i < pDesc->List.ListButtonCnt; i++)
    {
        pDesc->List.ButtonList[i].Valid       = TRUE;
        pDesc->List.ButtonList[i].ButtonIndex = i;
        pDesc->List.ButtonList[i].TxtId       = TxtId[i];     // Wday
        if ((1 == (RepeatBitmap >> 7)) && (1 == ((RepeatBitmap >> i) & 0x01)))
        {
            pDesc->List.ButtonList[i].SymbolId1 = SYMBOL_CHECKED;
        }
        else
        {
            pDesc->List.ButtonList[i].SymbolId1 = SYMBOL_NOT_CHECKED;
        }
        pDesc->List.ButtonList[i].ReleaseFun = Alarm_Proc_Btn_Repeat_Select_Wday;
    }

    pDesc->BtnBar.ButtonL.Valid = TRUE;
    pDesc->BtnBar.ButtonL.TxtId = PHONE_TEXT_ID_OK;
    pDesc->BtnBar.ButtonM.Valid = TRUE;
    pDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;
    pDesc->BtnBar.ButtonR.Valid = TRUE;
    pDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pDesc->KeyFunc              = Alarm_Proc_Key_Alarm_Repeat_Select;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_REPEAT_SELECT, &FuncList, pDesc);
} /* Display_Alarm_Repeat_Select */

/**
 * display Alarm Tone
 */
VOID Display_Alarm_Tone(VOID)
{
    Nav_Func_List_t            FuncList;
    UI_Normal_List_Only_Desc_t *pDesc = NULL;
    UINT32                     Size   = 0;
    UINT8                      i      = 0;

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_List_Only_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create_Common;
    FuncList.OnDestroy      = Alarm_Destroy_ListOnly;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Create_Common;

    pDesc = (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    pDesc->TitleBar.TxtId    = PHONE_TEXT_ID_ALARM_TONE;
    pDesc->TitleBar.TxtAlign = LV_LABEL_ALIGN_CENTER;

    pDesc->List.ListButtonCnt = 2;
    Size                      = sizeof(UI_Button_Desc_t) * pDesc->List.ListButtonCnt;
    pDesc->List.ButtonList    = (UI_Button_Desc_t *)Hal_Mem_Alloc(Size);
    Hal_Mem_Set(pDesc->List.ButtonList, 0, Size);

    pDesc->List.ButtonList[i].Valid        = TRUE;
    pDesc->List.ButtonList[i].ButtonIndex  = i;
    pDesc->List.ButtonList[i].TxtId        = PHONE_TEXT_ID_STANDARD;
    pDesc->List.ButtonList[i++].ReleaseFun = Alarm_Proc_Btn_Standard;

    pDesc->List.ButtonList[i].Valid        = TRUE;
    pDesc->List.ButtonList[i].ButtonIndex  = i;
    pDesc->List.ButtonList[i].TxtId        = PHONE_TEXT_ID_RINGING_TONE;
    pDesc->List.ButtonList[i++].ReleaseFun = Alarm_Proc_Btn_Ringing_Tone;

    pDesc->BtnBar.ButtonM.Valid = TRUE;
    pDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_SELECT;
    pDesc->BtnBar.ButtonR.Valid = TRUE;
    pDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pDesc->KeyFunc              = Alarm_Proc_Key_Alarm_Tone;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_TONE, &FuncList, pDesc);
} /* Display_Alarm_Tone */

/**
 * display Alarm Ringing Tone
 */
VOID Display_Alarm_Ringing_Tone(VOID)
{
    Nav_Func_List_t            FuncList;
    UI_Normal_List_Only_Desc_t *pDesc = NULL;
    UINT32                     Size   = 0;
    UINT8                      i      = 0;

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_List_Only_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create_Common;
    FuncList.OnDestroy      = Alarm_Destroy_ListOnly;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Create_Common;

    pDesc = (UI_Normal_List_Only_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_List_Only_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_List_Only_Desc_t));

    pDesc->TitleBar.TxtId    = PHONE_TEXT_ID_RINGING_TONE;
    pDesc->TitleBar.TxtAlign = LV_LABEL_ALIGN_CENTER;

    pDesc->List.ListButtonCnt = (ALARM_RING_TONE_COUNT - 1);
    Size                      = sizeof(UI_Button_Desc_t) * pDesc->List.ListButtonCnt;
    pDesc->List.ButtonList    = (UI_Button_Desc_t *)Hal_Mem_Alloc(Size);
    Hal_Mem_Set(pDesc->List.ButtonList, 0, Size);

    for (i = 0; i < pDesc->List.ListButtonCnt; i++)
    {
        pDesc->List.ButtonList[i].Valid       = TRUE;
        pDesc->List.ButtonList[i].ButtonIndex = i;
        pDesc->List.ButtonList[i].TxtId       = LV_LANG_TXT_ID_NONE;
        pDesc->List.ButtonList[i].BtnTxt      = (INT8 *)Hal_Mem_Alloc(20 * sizeof(INT8));
        strcpy(pDesc->List.ButtonList[i].BtnTxt, g_Alarm_Ringing_Tone[i + 1]);
        pDesc->List.ButtonList[i].ReleaseFun = Alarm_Proc_Btn_Ringing_Tone_Select;
    }

    pDesc->BtnBar.ButtonM.Valid = TRUE;
    pDesc->BtnBar.ButtonM.TxtId = PHONE_TEXT_ID_OK;
    pDesc->BtnBar.ButtonR.Valid = TRUE;
    pDesc->BtnBar.ButtonR.TxtId = PHONE_TEXT_ID_BACK;
    pDesc->KeyFunc              = Alarm_Proc_Key_Alarm_Ringing_Tone;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_RINGING_TONE, &FuncList, pDesc);
} /* Display_Alarm_Ringing_Tone */

/**
 * OnDestroy function
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Ring_OnDestroy(VOID *pDesc)
{
    UI_Normal_Alarm_Desc_t *AlarmDesc = (UI_Normal_Alarm_Desc_t *)pDesc;

    if (g_Alarm_Mng.Timer)
    {
        Hal_Timer_Stop(g_Alarm_Mng.Timer);
        g_Alarm_Mng.Timer = NULL;
    }

    lv_anim_del(AlarmDesc->Dsc, NULL);
    Hal_Mem_Free(AlarmDesc->Dsc);
    Hal_Mem_Free(pDesc);

    g_Alarm_Mng.CurrDesc = NULL;
}

/**
 * OnSaveState function
 * param (in) pDesc: VOID *
 * return VOID
 */
static VOID Alarm_Ring_OnSaveState(VOID *pDesc)
{
    UI_Normal_Alarm_Desc_t *AlarmDesc = (UI_Normal_Alarm_Desc_t *)pDesc;

    lv_anim_del(AlarmDesc->Dsc, NULL);
    Hal_Mem_Free(AlarmDesc->Dsc);
    AlarmDesc->Dsc = NULL;

    g_Alarm_Mng.CurrDesc = NULL;
}

/**
 * display Alarm Ring
 */
VOID Display_Alarm_Ring(UINT8 AlarmId)
{
    Nav_Func_List_t        FuncList;
    UI_Normal_Alarm_Desc_t *pDesc = NULL;
    UINT8                  Hour;
    UINT8                  Min;

    FuncList.OnShow         = (Void_P_Func_t)UI_Normal_Alarm_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create_Common;
    FuncList.OnDestroy      = Alarm_Ring_OnDestroy;
    FuncList.OnSaveState    = Alarm_Ring_OnSaveState;
    FuncList.OnRestoreState = Alarm_Create_Common;

    pDesc = (UI_Normal_Alarm_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Normal_Alarm_Desc_t));
    Hal_Mem_Set(pDesc, 0, sizeof(UI_Normal_Alarm_Desc_t));

    Min = g_Alarm_Mng.Alarm.AlarmInfo[AlarmId].Min
        + g_Alarm_Mng.Alarm.AlarmInfo[AlarmId].RepeatCount * ALARM_RING_REPEAT_INTERVAL;
    Hour = (g_Alarm_Mng.Alarm.AlarmInfo[AlarmId].Hour + Min / 60) % 24;
    Min  = Min % 60;
    pDesc->TitleBar.TxtAlign  = LV_LABEL_ALIGN_CENTER;
    pDesc->TitleBar.TxtId     = Alarm_Get_Alarm_Text_Id(AlarmId);
    pDesc->AnimLabel.TxtAlign = LV_LABEL_ALIGN_CENTER;
    pDesc->AnimLabel.TxtId    = (Hour << 8) + Min;

    pDesc->ButtonBar.ButtonM.Valid = TRUE;
    pDesc->ButtonBar.ButtonM.TxtId = PHONE_TEXT_ID_STOP;
    pDesc->ButtonBar.ButtonR.Valid = TRUE;
    pDesc->ButtonBar.ButtonR.TxtId = PHONE_TEXT_ID_SNOOZE;
    pDesc->KeyFunc                 = Alarm_Proc_Key_Alarm_Ring;

    Nav_Forward(ACT_ID_ANY, ACT_ID_ALARM_RING, &FuncList, pDesc);
}

/**
 * On destroy for Alarm_Status
 * param (in) Para: VOID *
 * return VOID
 */
VOID Alarm_Status_On_Destroy(VOID *Para)
{
    if (g_Alarm_Mng.StatusTimer)
    {
        Hal_Timer_Stop(g_Alarm_Mng.StatusTimer);
        g_Alarm_Mng.StatusTimer = NULL;
    }
    Alarm_Destroy_Common(Para);
}

/**
 * display Alarm_Status UI
 * param (in) ActId:  ACTIVITY_ID
 * return VOID
 */
VOID Display_Alarm_Status(ACTIVITY_ID ActId)
{
    Nav_Func_List_t  FuncList;
    UI_Status_Desc_t *pDesc;

    FuncList.OnShow         = (Void_P_Func_t)UI_Status_Create;
    FuncList.OnHide         = NULL;
    FuncList.OnCreate       = Alarm_Create_Common;
    FuncList.OnDestroy      = Alarm_Status_On_Destroy;
    FuncList.OnSaveState    = NULL;
    FuncList.OnRestoreState = Alarm_Create_Common;

    pDesc = (UI_Status_Desc_t *)Hal_Mem_Alloc(sizeof(UI_Status_Desc_t));
    memset(pDesc, 0, sizeof(UI_Status_Desc_t));

    /* set TxtId of Status UI */
    switch (ActId)
    {
    case ACT_ID_ALARM_ON:
        pDesc->ContLabel.TxtId = PHONE_TEXT_ID_ALARM_ON;
        break;

    case ACT_ID_ALARM_OFF:
    case ACT_ID_ALARM_RING_OFF:
        pDesc->ContLabel.TxtId = PHONE_TEXT_ID_ALARM_OFF;
        break;

    case ACT_ID_ALARM_RING_DELAY:
        pDesc->ContLabel.TxtId = PHONE_TEXT_ID_ALARM_DELAY;
        break;

    case ACT_ID_ALARM_ONCE_SELECTED:
        pDesc->ContLabel.TxtId = PHONE_TEXT_ID_ALARM_ONCE_SELECTED;
        break;

    case ACT_ID_ALARM_REPEAT_SELECTED:
        pDesc->ContLabel.TxtId = PHONE_TEXT_ID_ALARM_REPEAT_SELECTED;
        break;

    case ACT_ID_ALARM_TONE_SELECTED:
        pDesc->ContLabel.TxtId = PHONE_TEXT_ID_ALARM_TONE_SELECTED;
        break;

    default:
        break;
    }
    pDesc->ContLabel.TxtAlign   = LV_LABEL_ALIGN_LEFT;
    pDesc->ContLabel.LabelAlign = LV_ALIGN_IN_TOP_LEFT;
    pDesc->ContLabelAlign       = LV_ALIGN_IN_TOP_LEFT;
    pDesc->ContImg.Img          = LV_SYMBOL_OK;
    pDesc->ContImgAlign         = LV_ALIGN_IN_TOP_RIGHT;

    pDesc->KeyFunc = NULL;

    Nav_Forward(ACT_ID_ANY, ActId, &FuncList, pDesc);
    g_Alarm_Mng.SrcActId = ActId;
    g_Alarm_Mng.StatusTimer = Hal_Timer_Start(ALARM_STATUS_TIMER_LEN,
                                              Alarm_Proc_Status_Timeout,
                                              NULL,
                                              FALSE);// start display timer one time
} /* Display_Alarm_Status */
